module framework.Renderer;
import std.string;
import derelict.sdl.sdl;
import derelict.opengl.gl;
import derelict.opengl.glu;
import framework.JobHub;

Renderer _renderer;

static this(){
	_renderer=new Renderer();
}

Renderer renderer(){
	return _renderer;
}

class Renderer{
	
	private {
		// horizontal and vertical screen resolution
		const int   xResolution     = 800;
		const int   yResolution     = 600;
		
		// number of bits per pixel used for display. 24 => true color
		const int   bitsPerPixel    = 24;
		
		// field of view => the angle our camera will see vertically
		const float fov             = 90.f;
		
		// distance of the near clipping plane
		const float nearPlane       = .1f;
		
		// distance of the far clipping plane
		const float farPlane        = 100.f;
		
		
		/**
		  Setup some basic OpenGL parameters
		*/
		void setupGL() {
		
			// switch to the projection mode matrix
			glMatrixMode(GL_PROJECTION);
		
			// load the identity matrix for projection
			glLoadIdentity();
		
			// setup a perspective projection matrix
			gluPerspective(fov, cast(float)xResolution / yResolution, nearPlane, farPlane);
		
			// switch back to the modelview transformation matrix
			glMatrixMode(GL_MODELVIEW);
		
			// load the identity matrix for modelview
			glLoadIdentity();
		}
		
		
		void init() {
			// initialize SDL, GL and GLU Derelict modules
			DerelictSDL.load();
			DerelictGL.load();
			DerelictGLU.load();
		
			// initialize SDL's VIDEO module
			SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
		
			// enable double-buffering
			SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
		
			// create our OpenGL window
			SDL_SetVideoMode(xResolution, yResolution, bitsPerPixel, SDL_OPENGL);
			SDL_WM_SetCaption(toStringz("My SDL Window"), null);
		
			setupGL();
		}
		
		
		// be nice and release all resources
		void cleanup() {
			// tell SDL to quit
			SDL_Quit();
		
			// release GL, GLU and SDL's shared libs
			DerelictGLU.unload();
			DerelictGL.unload();
			DerelictSDL.unload();
		}
	}

	
	this(){
		init();
		jobHub.register(&this.update);
	}
	
	~this(){
		cleanup();
	}
	
	private void delegate()[] dels;
	
	void register(void delegate() del){
		dels ~=del;
	}
	
	
	void update(){
		
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
		glClearColor ( 0.2, 0.2, 0.2 , 0);
		glLoadIdentity();
		foreach(del;dels){
			del();
		}
		SDL_GL_SwapBuffers();
	}
}

